#include "db.h"
#include "util.h"
#include "table.h"
#include <string>
#include <fstream>
#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

DB my_db[100];
int my_db_num = 0;
TABLE all_table[100];
std::string table_data[100][100];
std::string dbPath;

//读取数据库状态
void read_db(){
    my_db_num = 0;
    const std::string my_db_filename = dbPath + "/my_db.txt";
    //打开文件，若不存在，创建新文件
    std::ifstream in_file(my_db_filename,std::ios::in);
   
    while (in_file.peek() != EOF)
    {
        in_file >> my_db[my_db_num].table_name;
        in_file >> my_db[my_db_num].file_name;
        in_file >> my_db[my_db_num].index;
        if (is_not_endl(my_db[my_db_num].table_name[0]) == 1)
            my_db_num++;
    }
 
    in_file.close();
}

//写入数据库状态
void write_db(){
    const std::string my_db_filename = dbPath + "/my_db.txt";
    std::ofstream out_file(my_db_filename);
    for(int i = 0; i < my_db_num;i++){
       //表名 文件名 下标
        out_file << my_db[i].table_name << " ";
        out_file << my_db[i].file_name << " ";
        out_file << my_db[i].index << std::endl;
    }
    out_file.close();
}

// 读取所有表格和属性
void read_all_tables(){
    table_num = 0;
    for(int i = 0;i < my_db_num;i++){
        //通过每一行得到一张表
        int index = my_db[i].index;
        all_table[index].table_name = my_db[i].table_name;
        all_table[index].file_name = my_db[i].file_name;
        read_table(index,dbPath+"/"+my_db[i].file_name);
        if(is_not_endl(all_table[index].file_name[0]) == 1){
            table_num++;
        }
    }
}

//读取表头
void read_table(int index, std::string filename){
    all_table[index].col_num = 0;

    //打开文件，不存在则创建
    std::ifstream in_file(filename, std::ios::in);
    std:: string s;
    getline(in_file,s);
    int i = 0;

    //解析表头
    while(i < (int)s.size()){
        int k = 0;
        std::string str;
        std::string str_type;
        if(s[i + k] == ' ') i++;
        while((i+k) != (int)s.size() && s[i+k] != '('){
            str += s[i+k];
            k++;
        }
        k++;
        while ((i+k) != (int)s.size() && s[i+k] != ')')
        {
            str_type += s[i+k];
            k++;
        }
        
        int c = all_table[index].col_num;
        all_table[index].column[c] = str;
        all_table[index].type[c] = str_type;
        all_table[index].col_num++;
        i = i + k + 2;
    }
    in_file.close();
}

//写表头
void write_table(int index, std::string filename)
{
    std::ofstream out_file(dbPath+"/"+filename, std::ios::out);
    for (int i = 0; i < all_table[index].col_num; i++)
        out_file << all_table[index].column[i] + '('+ all_table[index].type[i] + ')'<< " ";
    out_file << std::endl;
    out_file.close();
}

//读数据

void read_table_data(int index, std::string filename)
{
    all_table[index].row_num = 0; //读入表头前先将表格行数归零
 
     //打开文件，若文件不存在，则创建文件
    std::ifstream in_file(filename, std::ios::in);
 
    //先读表头
    std::string s;
    getline(in_file, s);
 
    //剩下的是表格数据
    while(!in_file.eof())
    {
        for (int j = 0; j < all_table[index].col_num; j++)
            in_file >> table_data[all_table[index].row_num][j]; //用二维数组接受表格信息
        if(table_data[all_table[index].row_num][0]>="0" && table_data[all_table[index].row_num][0]<="9")
            all_table[index].row_num++;
    }    
    in_file.close();
}

//写数据

void write_table_data(int index, std::string filename)
{
    std::ofstream out_file(filename, std::ios::out | std::ios::trunc);
    //写入表头
    for (int i = 0; i < all_table[index].col_num; i++)
    {
        std::string data = all_table[index].column[i] + "(" + all_table[index].type[i] + ")";
        out_file << data << " ";
    }
    out_file << std::endl;
    
    //写入数据
    for (int i = 0; i < all_table[index].row_num; i++)
    {
        for (int j = 0; j < all_table[index].col_num; j++)
        {
            out_file << table_data[i][j]<<" ";
        }
        out_file << std::endl;
    }
    out_file.close();
}

void create_db(char ins[]){
    std::string dbname;
    int i = 16;
    while(i < 99 &&ins[i] != ' ' ){
        dbname += ins[i];
        i++;
    }
    std::string base = "data";
    fs::path currentPath = fs::current_path();
    fs::path folderPath = currentPath/base/dbname;
     if (fs::create_directory(folderPath)) {
        std::cout << "数据库创建成功: "  << dbname<< std::endl;
    } else {
        std::cout << "数据库已存在: " << dbname << std::endl;
    }

}
void drop_db(char ins[]){
    std::string dbname;
    int i = 14;
    while(i < 99 &&ins[i] != ' ' ){
        dbname += ins[i];
        i++;
    }
    std::string base = "data";
    fs::path currentPath = fs::current_path();
    fs::path folderPath = currentPath/base/dbname;
    if (fs::exists(folderPath) && fs::is_directory(folderPath)) {
    if (fs::remove_all(folderPath)) {
        std::cout<< "已删除数据库: " <<dbname<<std::endl;
    } else {
        std::cout<< "删除数据库失败: " <<dbname<<std::endl;
    }
} else {
    std::cout<< "数据库不存在: " <<dbname<<std::endl;
}
}

void use_db(char ins[]){
    read_db();
    std::string dbname;
    int i = 4;
    while(i < 99 &&ins[i] != ' ' ){
        dbname += ins[i];
        i++;
    }
    if(dbname.empty()){
        std::cout<< "请填写数据库" <<dbname<<std::endl;
    }
    std::string base = "data";
    fs::path currentPath = fs::current_path();
    fs::path folderPath = currentPath/base/dbname;
    if(fs::exists(folderPath)){
        dbPath = folderPath.c_str();
        std::cout<<dbPath<<std::endl;
        std::cout<< "切换至数据库: " <<dbname<<std::endl;
    }else{
        std::cout<< "数据库不存在: " <<dbname<<std::endl;
    }

}

//找到对应表格，i是表名开始的地方
int find_table(char ins[], int i){
    //解析指令获取表名
        std::string tablename;
        while (ins[i] != '\0' && ins[i] != ' ')
        {
            tablename += ins[i];
            i++;
        }
 
        //根据表名打开对应文件，读取表格数据
        int index;
        std::string filename;
        bool flag = 1;
        for (int j = 0; j < my_db_num; j++)
        {
            if (my_db[j].table_name == tablename)
            {
                //找到了对应的表格
                index = my_db[j].index;
                filename = my_db[j].file_name;
                read_table_data(index,dbPath+"/"+filename);
                flag = 0;
                break;
            }
        }
        if (flag == 1) //没找到
        {
            std::cout << "Not found TABLE " << tablename << " !" << std::endl;
            return -1;
        }
        return index;
}
